package com.android.lovely.ui.widget

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.util.TypedValue
import android.view.MotionEvent
import android.view.View
import com.android.lovely.R


/**
 *
 * @author why
 * @date 2025/3/30 16:56
 */
class AlphabetTouchView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    private var mAlphabet: String? = null
    private lateinit var mTextPaint: Paint
    private var mBubblePaint: Paint? = null
    private var mTextSize = 0
    private var mTextColor = 0
    private var mSelectedTextColor = Color.RED
    private var mWidth = 0
    private var mHeight = 0
    private var mLetterHeight = 0f
    private var mSelectedIndex = -1

    private var mListener: OnLetterSelectedListener? = null

    fun setOnLetterSelectedListener(listener: OnLetterSelectedListener?) {
        mListener = listener
    }


    init {
        val a = context.theme.obtainStyledAttributes(
            attrs,
            R.styleable.AlphabetTouchView,
            0, 0
        )

        try {
            mTextSize = a.getDimensionPixelSize(R.styleable.AlphabetTouchView_textSize, 14)
            mTextColor = a.getColor(R.styleable.AlphabetTouchView_textColor, Color.BLACK)
            mSelectedTextColor =
                a.getColor(R.styleable.AlphabetTouchView_selectedTextColor, Color.RED)
            mAlphabet = a.getString(R.styleable.AlphabetTouchView_alphabet)
            if (mAlphabet == null || mAlphabet.isNullOrEmpty()) {
                mAlphabet = DEFAULT_ALPHABET
            }
        } finally {
            a.recycle()
        }


        init()
    }

    private fun sp2px(sp: Int): Float {
        return TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_SP,
            sp.toFloat(),
            resources.displayMetrics
        )
    }

    private fun init() {
        mTextPaint = Paint()
        mTextPaint?.color = mTextColor
        mTextPaint?.textSize = sp2px(mTextSize)
        mTextPaint?.isAntiAlias = true

        mBubblePaint = Paint()
        mBubblePaint?.color = Color.parseColor("#AA0000")
        mBubblePaint?.isAntiAlias = true
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        mWidth = w
        mHeight = h
        mLetterHeight = mHeight.toFloat() / (mAlphabet?.length ?: 0)
    }

    override fun onDraw(canvas: Canvas) {
        // 绘制26个字母

        val fontMetrics = mTextPaint.fontMetrics // 获取字体的度量信息
        val fontHeight = fontMetrics.descent - fontMetrics.ascent // 字体高度

        for (i in 0 until (mAlphabet?.length ?: 0)) {
            // 计算字母的x坐标，使字母居中 ,x = mWidth / 2 - 文字的宽度 / 2
            val x = mWidth / 2 - mTextPaint.measureText(mAlphabet?.get(i).toString()) / 2

            // 计算字母的y坐标，使用均匀分布的间距
            // i * mLetterHeight: 当前字母所在的格子的顶部位置
            // (mLetterHeight + fontHeight) / 2 : 计算字母在格子中应该偏移多少才能垂直居中
            // - fontMetrics.descent : 确保基线（baseline）正确对齐,fontMetrics.descent是从基线到字母底部的距离，所以减去这一部分能使得字母真正的中心对齐到格子的中心。
            val y = i * mLetterHeight + (mLetterHeight + fontHeight) / 2 - fontMetrics.descent

            if (i == mSelectedIndex) {
                // 选中的字母文字颜色设置为选中颜色
                mTextPaint.color = mSelectedTextColor
            } else {
                // 否则，使用普通的文字颜色
                mTextPaint.color = mTextColor
            }

            // 绘制字母
            canvas.drawText(mAlphabet?.get(i).toString(), x, y, mTextPaint)
        }
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        val action = event.action
        val touchY = event.y

        when (action) {
            MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {
                // 根据触摸的Y坐标来计算字母的索引
                // 获取触摸点所在的字母
                val index = (touchY / (mHeight / (mAlphabet?.length ?: 0))).toInt()
                if (index >= 0 && index < (mAlphabet?.length ?: 0)) {
                    mSelectedIndex = index
                    if (mListener != null) {
                        mListener?.onLetterSelected(touchY,mAlphabet?.get(mSelectedIndex).toString(), true)
                    }
                    invalidate()
                }
            }

            MotionEvent.ACTION_UP -> {
                if (mListener != null) {
                    mListener?.onLetterSelected(
                        touchY,
                        mAlphabet?.get(mSelectedIndex).toString(),
                        false
                    )
                }
                mSelectedIndex = -1
                invalidate()
            }
        }
        return true
    }

    interface OnLetterSelectedListener {
        fun onLetterSelected(touchY: Float, letter: String?, isTouch: Boolean)
    }

    companion object {
        private const val DEFAULT_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ#"
    }
}